#!/usr/bin/env python
# -*- coding: UTF-8 -*-

import os
import sys
import requests
from io import BytesIO
from PIL import Image
import time
import random

# 添加项目路径到系统路径
project_path = os.path.join(os.path.dirname(__file__), '..')
sys.path.append(project_path)

# 导入MinIO客户端
from backend.tools.minio_client import minio_client

class AdvancedImageCrawler:
    """高级真实图片爬虫类"""
    
    def __init__(self):
        """初始化爬虫"""
        self.headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
        }
        
        # 项目需要的图片列表和对应的搜索关键词
        self.image_requirements = {
            'banners': [
                {"name": "banner1", "keywords": ["massage", "therapy", "relaxation"], "width": 600, "height": 300},
                {"name": "banner2", "keywords": ["spa", "treatment", "wellness"], "width": 600, "height": 300}
            ],
            'icons': [
                {"name": "massage", "keywords": ["massage", "hands", "therapy"], "width": 100, "height": 100},
                {"name": "spa", "keywords": ["spa", "lotus", "water"], "width": 100, "height": 100},
                {"name": "footcare", "keywords": ["foot", "massage", "feet"], "width": 100, "height": 100},
                {"name": "bodycare", "keywords": ["body", "care", "wellness"], "width": 100, "height": 100}
            ],
            'avatars': [
                {"name": "technician1", "keywords": ["massage therapist", "professional"], "width": 200, "height": 200},
                {"name": "technician2", "keywords": ["spa therapist", "woman"], "width": 200, "height": 200},
                {"name": "technician3", "keywords": ["beauty therapist", "person"], "width": 200, "height": 200}
            ],
            'services': [
                {"name": "service1", "keywords": ["full body massage", "relaxation"], "width": 200, "height": 200},
                {"name": "service2", "keywords": ["foot massage", "feet care"], "width": 200, "height": 200}
            ]
        }
        
        # 真实图片API端点
        self.api_endpoints = {
            'unsplash': 'https://api.unsplash.com/search/photos',
            'pexels': 'https://api.pexels.com/v1/search',
            'pixabay': 'https://pixabay.com/api/'
        }
        
        # API密钥（需要用户自己配置）
        self.api_keys = {
            'unsplash': os.environ.get('UNSPLASH_ACCESS_KEY', ''),
            'pexels': os.environ.get('PEXELS_API_KEY', ''),
            'pixabay': os.environ.get('PIXABAY_API_KEY', '')
        }
    
    def search_images_from_unsplash(self, keywords, count=3):
        """
        从Unsplash搜索图片
        :param keywords: 搜索关键词列表
        :param count: 返回图片数量
        :return: 图片信息列表
        """
        if not self.api_keys['unsplash']:
            print("未配置Unsplash API密钥")
            return []
        
        try:
            query = ' '.join(keywords)
            params = {
                'query': query,
                'per_page': count,
                'orientation': 'landscape'
            }
            headers = {
                'Authorization': f'Client-ID {self.api_keys["unsplash"]}'
            }
            
            response = requests.get(
                self.api_endpoints['unsplash'], 
                params=params, 
                headers=headers, 
                timeout=10
            )
            
            if response.status_code == 200:
                data = response.json()
                images = []
                for photo in data.get('results', []):
                    images.append({
                        'url': photo['urls']['regular'],
                        'width': photo['width'],
                        'height': photo['height'],
                        'description': photo.get('description', '')
                    })
                return images
        except Exception as e:
            print(f"从Unsplash搜索图片失败: {e}")
        
        return []
    
    def search_images_from_pexels(self, keywords, count=3):
        """
        从Pexels搜索图片
        :param keywords: 搜索关键词列表
        :param count: 返回图片数量
        :return: 图片信息列表
        """
        if not self.api_keys['pexels']:
            print("未配置Pexels API密钥")
            return []
        
        try:
            query = ' '.join(keywords)
            params = {
                'query': query,
                'per_page': count
            }
            headers = {
                'Authorization': self.api_keys['pexels']
            }
            
            response = requests.get(
                self.api_endpoints['pexels'], 
                params=params, 
                headers=headers, 
                timeout=10
            )
            
            if response.status_code == 200:
                data = response.json()
                images = []
                for photo in data.get('photos', []):
                    images.append({
                        'url': photo['src']['large'],
                        'width': photo['width'],
                        'height': photo['height'],
                        'photographer': photo.get('photographer', '')
                    })
                return images
        except Exception as e:
            print(f"从Pexels搜索图片失败: {e}")
        
        return []
    
    def search_images_from_pixabay(self, keywords, count=3):
        """
        从Pixabay搜索图片
        :param keywords: 搜索关键词列表
        :param count: 返回图片数量
        :return: 图片信息列表
        """
        if not self.api_keys['pixabay']:
            print("未配置Pixabay API密钥")
            return []
        
        try:
            query = '+'.join(keywords)
            params = {
                'key': self.api_keys['pixabay'],
                'q': query,
                'per_page': count,
                'image_type': 'photo'
            }
            
            response = requests.get(
                self.api_endpoints['pixabay'], 
                params=params, 
                timeout=10
            )
            
            if response.status_code == 200:
                data = response.json()
                images = []
                for hit in data.get('hits', []):
                    images.append({
                        'url': hit['largeImageURL'],
                        'width': hit['imageWidth'],
                        'height': hit['imageHeight'],
                        'tags': hit.get('tags', '')
                    })
                return images
        except Exception as e:
            print(f"从Pixabay搜索图片失败: {e}")
        
        return []
    
    def search_authentic_images(self, keywords, count=3):
        """
        从多个源搜索真实图片
        :param keywords: 搜索关键词列表
        :param count: 返回图片数量
        :return: 图片信息列表
        """
        print(f"正在搜索关键词: {', '.join(keywords)}")
        
        # 尝试多个图片源
        search_functions = [
            self.search_images_from_unsplash,
            self.search_images_from_pexels,
            self.search_images_from_pixabay
        ]
        
        for search_func in search_functions:
            try:
                images = search_func(keywords, count)
                if images:
                    print(f"从 {search_func.__name__} 找到 {len(images)} 张图片")
                    return images
            except Exception as e:
                print(f"搜索函数 {search_func.__name__} 失败: {e}")
                continue
            
            # 添加延迟避免被封
            time.sleep(random.uniform(1, 2))
        
        return []
    
    def download_image(self, url):
        """
        下载图片
        :param url: 图片URL
        :return: 图片二进制数据
        """
        try:
            print(f"正在下载图片: {url}")
            response = requests.get(url, headers=self.headers, timeout=15)
            if response.status_code == 200:
                content_type = response.headers.get('content-type', '')
                if 'image' in content_type:
                    print("图片下载成功")
                    return response.content
                else:
                    print(f"URL不是图片: {content_type}")
            else:
                print(f"下载失败，状态码: {response.status_code}")
        except Exception as e:
            print(f"下载图片失败: {e}")
        
        return None
    
    def resize_image(self, image_data, max_width, max_height):
        """
        调整图片大小
        :param image_data: 图片二进制数据
        :param max_width: 最大宽度
        :param max_height: 最大高度
        :return: 调整后的图片二进制数据
        """
        try:
            image = Image.open(BytesIO(image_data))
            
            # 如果图片尺寸超过限制，则调整大小
            if image.width > max_width or image.height > max_height:
                image.thumbnail((max_width, max_height), Image.Resampling.LANCZOS)
            
            # 转换为RGB模式（如果需要）
            if image.mode in ('RGBA', 'LA', 'P'):
                # 创建白色背景
                background = Image.new('RGB', image.size, (255, 255, 255))
                if image.mode == 'P':
                    image = image.convert('RGBA')
                background.paste(image, mask=image.split()[-1] if image.mode in ('RGBA', 'LA') else None)
                image = background
            
            # 保存为JPEG格式
            output = BytesIO()
            image.save(output, format='JPEG', quality=85)
            return output.getvalue()
        except Exception as e:
            print(f"调整图片大小失败: {e}")
            return image_data  # 返回原始数据
    
    def upload_to_minio(self, image_data, folder, filename):
        """
        上传图片到MinIO
        :param image_data: 图片二进制数据
        :param folder: 存储文件夹
        :param filename: 文件名
        :return: 图片URL
        """
        try:
            object_name = f"{folder}/{filename}"
            minio_client.upload_bytes(object_name, image_data, content_type="image/jpeg")
            url = minio_client.presigned_get_url(object_name)
            return url
        except Exception as e:
            print(f"上传图片到MinIO失败: {e}")
            return None
    
    def crawl_and_upload_all_images(self):
        """
        爬取并上传所有需要的真实图片
        """
        print("开始爬取并上传所有真实图片...")
        
        # 存储所有图片URL
        image_urls = {}
        
        # 按类别爬取图片
        for category, images in self.image_requirements.items():
            print(f"\n=== 爬取 {category} 类别图片 ===")
            category_urls = {}
            
            for img_info in images:
                name = img_info["name"]
                keywords = img_info["keywords"]
                width = img_info["width"]
                height = img_info["height"]
                
                print(f"\n--- 爬取 {name} ({', '.join(keywords)}) ---")
                
                # 搜索真实图片
                image_results = self.search_authentic_images(keywords, 3)
                if image_results:
                    # 选择第一张图片下载
                    selected_image = image_results[0]
                    image_data = self.download_image(selected_image['url'])
                    
                    if image_data:
                        # 调整大小
                        resized_data = self.resize_image(image_data, width, height)
                        # 上传到MinIO
                        filename = f"{name}.jpg"
                        url = self.upload_to_minio(resized_data, category, filename)
                        if url:
                            category_urls[name] = url
                            print(f"{name} 上传成功: {url}")
                        else:
                            print(f"{name} 上传失败")
                    else:
                        print(f"{name} 下载失败")
                else:
                    print(f"{name} 搜索失败")
                
                # 添加延迟
                time.sleep(random.uniform(2, 4))
            
            image_urls[category] = category_urls
        
        print("\n所有真实图片爬取和上传完成!")
        return image_urls

def main():
    """主函数"""
    print("高级真实图片爬虫")
    print("注意：需要配置API密钥才能获取最佳效果")
    print("请设置以下环境变量：")
    print("  UNSPLASH_ACCESS_KEY  - Unsplash API访问密钥")
    print("  PEXELS_API_KEY       - Pexels API密钥")
    print("  PIXABAY_API_KEY      - Pixabay API密钥")
    print()
    
    crawler = AdvancedImageCrawler()
    urls = crawler.crawl_and_upload_all_images()
    
    print("\n=== 真实图片URL汇总 ===")
    for category, url_dict in urls.items():
        print(f"\n{category}:")
        for name, url in url_dict.items():
            print(f"  {name}: {url}")

if __name__ == "__main__":
    main()